
#include "bsp.h"
#include "esp_log.h"

static const char *TAG = "Protocol";


/*******************************************************************************
* 功能描述	: 接收数据校验和累加处理函数
* 参数一    : data  数据指针
* 参数二    : size  数据长度
* 返回参数  : 校验成功==0，校验失败==-1
********************************************************************************
*修改日期             修改人          修改备注
*20211115            umi             初始版本
*******************************************************************************/
uint8_t Tospo_CheckSum( char *data,size_t size)
{
    //esp_err_t ret  = ESP_OK;
    uint32_t count = 0;
    uint8_t checksum=0;
    for(count=0;count<(size-1);count++)
    {
        checksum += data[count];
    }

    if(checksum == data[size-1])
    {
        return ESP_OK;
    }
    else
    {
        return ESP_FAIL;
    }
}

/*******************************************************************************
* 功能描述	: 判断此帧数据是否发送给本设备的
* 参数一    : channal  通道
* 参数二    : row  行
* 参数二    : col  列
* 返回参数  : 验证成功==0，验证失败==-1
********************************************************************************
*修改日期             修改人          修改备注
*20211115            umi             初始版本
*******************************************************************************/
uint8_t Tospo_Is_MyData(uint8_t channal,uint8_t row,uint8_t col)
{
    //esp_err_t ret  = ESP_OK;

    if(channal == App.Tosop_Edu_Channel)
    {
        if((row == App.Tosop_Edu_Row) && (col == App.Tosop_Edu_column))//指定行列
        {
            return ESP_OK;
        }
        else if((row == 0xFF) && (col == 0xFF))//广播
        {
           return ESP_OK; 
        }
        else
        {
           return ESP_FAIL; 
        }
    }
    else
    {
        return ESP_FAIL;
    }
}



/*******************************************************************************
* 功能描述	: 处理接收到的espnow数据
* 参数一    : src_addr  发送方的MAC地址
* 参数二    : data  接收的数据
* 参数三    : size  数据长度
* 参数四    : rx_ctrl  无线的一些参数信息
* 返回参数  : 处理成功==0，处理失败==x
********************************************************************************
*修改日期             修改人          修改备注
*20211112            umi             初始版本
*******************************************************************************/
uint8_t Tospo_espnow_process_data(uint8_t *src_addr, void *data,size_t *size, wifi_pkt_rx_ctrl_t *rx_ctrl)
{
    esp_err_t ret  = ESP_OK;
    uint32_t count = 0;
    char *recv_data=NULL;     //= ESP_MALLOC(ESPNOW_DATA_LEN);
    //size_t recv_size   = ESPNOW_DATA_LEN;
    //uint8_t addr[ESPNOW_ADDR_LEN] = {0};
    //wifi_pkt_rx_ctrl_t rx_ctrl_data    = {0};

    //打印出src_addr
    ESP_LOGI(TAG, "SRC_MAC_ADDR==[" MACSTR "]", MAC2STR(src_addr));

   //打印出接收信号强度
    //rx_ctrl_data = rx_ctrl;
    ESP_LOGI(TAG, "rx_ctrl.rssi==%d",rx_ctrl->rssi);

    //打印出接收数据长度
    //recv_size = *size;
    ESP_LOGI(TAG, "Data_Size==%d",*size);

    //打印出接收数据
    recv_data  = (char *)data;
    printf("Recv_data==");
    for(count=0;count<*size;count++)
    {
        printf("%x-",recv_data[count]);
    }
    printf("\r\n");

    //下面是进行协议数据梳理

    //首先进行校验和，从第一位加到倒数第二位
    ret=Tospo_CheckSum((char *)data,*size);
    ESP_LOGI(TAG, "Tospo_CheckSum_ret==%d",ret);

    ret = ESP_OK;//调试阶段屏蔽校验和
    if(ret == ESP_OK)//校验和正确
    {
        if((recv_data[0]==HEAD_ONE)&&(recv_data[1]==HEAD_TWO)&&(recv_data[2]==COLTD_ONE)&&(recv_data[3]==COLTD_TWO))//验证前四个固定字节
        {
            if(recv_data[4] == PROTOCOL_TYPE_ONE)//正常数据传输
            {
                if(App.Tosop_Is_CONNECT_FLAG == 1)//确保组网成功才可以接收
                {
                    ret=Tospo_Is_MyData(recv_data[5],recv_data[6],recv_data[7]);//校验通道和行，列
                    ESP_LOGI(TAG, "Tospo_Is_MyData_ret==%d",ret);
                    //ret = ESP_OK;//调试阶段屏蔽行列
                    if(ret == ESP_OK)//校验和正确
                    {
                        if(recv_data[8] == PROTOCOL_TYPE_ONE_CMD_ONE)//协议类型一之正常数据传输下的命令字一：开关灯
                        {
                            if(recv_data[11] == PROTOCOL_TYPE_ONE_CMD_ONE_OPEN)//开灯
                            {
                                ESP_LOGI(TAG, "Turn on the Light");
                                Relay_ON;
                                LED_ON;
                                //gpio_set_level(GPIO_OUTPUT_IO_0, 1);
                                //gpio_set_level(GPIO_OUTPUT_IO_1, 1);
                            }
                            else//关灯
                            {
                                ESP_LOGI(TAG, "Turn off the Light");
                                Relay_OFF;
                                LED_OFF;
                                //gpio_set_level(GPIO_OUTPUT_IO_0, 0);
                                //gpio_set_level(GPIO_OUTPUT_IO_1, 0);
                            }
                        }
                        else if(recv_data[8] == PROTOCOL_TYPE_ONE_CMD_TWO)//协议类型一之正常数据传输下的命令字二：调光
                        {
                            ESP_LOGI(TAG, "PROTOCOL_TYPE_ONE_CMD_TWO==%d=%x",recv_data[11],recv_data[11]); 
                            Tospo_Ledc_PPM_Set_duty(recv_data[11]);
                        }
                        else{}
                    }
                    else{}
                }
            }
            else if(recv_data[4] == PROTOCOL_TYPE_TWO)//配网参数设置
            {
                //如果接到的信号值大于-30db才可以设置
                if(rx_ctrl->rssi > -35)
                {

                    if(recv_data[8] == PROTOCOL_TYPE_TWO_CMD_ONE)//协议类型二之配网参数设置下的命令字01：设置通道+列数+行数
                    {   
                        ESP_LOGI(TAG, "recv_data[11]==%d=%x",recv_data[11],recv_data[11]); 
                        ESP_LOGI(TAG, "recv_data[12]==%d=%x",recv_data[12],recv_data[12]); 
                        ESP_LOGI(TAG, "recv_data[13]==%d=%x",recv_data[13],recv_data[13]); 

                        App.Tosop_Is_CONNECT_FLAG=1;
                        App.Tosop_Edu_Channel = recv_data[11];
                        App.Tosop_Edu_Row = recv_data[12];
                        App.Tosop_Edu_column = recv_data[13];

                        Tospo_DataBase_Save();
                        ESP_LOGI(TAG, "Tospo_DataBase_Save OK!!!");
                    }
                    else if(recv_data[8] == PROTOCOL_TYPE_TWO_CMD_TWO)//协议类型二之配网参数设置下的命令字02：清除三个参数
                    {
                        
                        App.Tosop_Is_CONNECT_FLAG=0;
                        App.Tosop_Edu_Channel = 0xFF;
                        App.Tosop_Edu_Row = 0xFF;
                        App.Tosop_Edu_column = 0xFF;
                        
                        Tospo_DataBase_Save();
                        ESP_LOGI(TAG, "Data clear OK!!!");

                    }
                    else if(recv_data[8] == PROTOCOL_TYPE_TWO_CMD_THR)//协议类型二之配网参数设置下的命令字03：请求组网信息
                    {

                        //ESP_LOGI(TAG, "PROTOCOL_TYPE_TWO_CMD_THR  OK! OK!");
                    }
                    else{}

                }
                else
                {
                    ESP_LOGI(TAG, "rx_ctrl->rssi==%d",rx_ctrl->rssi);
                }


                if(recv_data[8] == PROTOCOL_TYPE_TWO_CMD_FOU)//协议类型二之配网参数设置下的命令字04：全开
                {

                    ESP_LOGI(TAG, "LIGHT ON");
                    //gpio_set_level(GPIO_OUTPUT_IO_1, 1);
                    Relay_ON;
                    LED_ON;
                }
                else if(recv_data[8] == PROTOCOL_TYPE_TWO_CMD_FIV)//协议类 型二之配网参数设置下的命令字05：全关
                {

                    ESP_LOGI(TAG, "LIGHT OFF");
                    //gpio_set_level(GPIO_OUTPUT_IO_1, 0);
                    Relay_OFF;
                    LED_OFF;
                }else{}


            }
            else{}
        }
        else
        {
            ESP_LOGI(TAG,"Head and coltd Error");
        }
    }
    else
    {
        ESP_LOGI(TAG,"Check Sum Error");
    }

   

 
    




    return 0; 
}







